﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Timers;
using AhpilyServer.Concurrent;

namespace AhpilyServer.TimerUtil
{
    /// <summary>
    /// 定时任务 管理类
    /// </summary>
    public class TimerManager
    {
        public static TimerManager Instance
        {
            get
            {
                lock (instance)
                {
                    if (instance == null)
                    {
                        instance = new TimerManager();
                    }
                    return instance;
                }
            }
        }
        private static TimerManager instance;
        /// <summary>
        /// 实现定时器主要功能的就是这个Timer类
        /// </summary>
        private Timer mTimer;
        /// <summary>
        /// 根据ID存储 任务模型 的字典
        /// </summary>
        private ConcurrentDictionary<int, TimerModel> mDictTimerModel = new ConcurrentDictionary<int, TimerModel>();
        /// <summary>
        /// 将要移除任务的ID表
        /// </summary>
        private List<int> mRemoveList = new List<int>();
        /// <summary>
        /// 用来表示ID
        /// </summary>
        ConcurrentInt id = new ConcurrentInt(-1);

        public TimerManager()
        {
            //每10ms触发一次
            mTimer = new Timer(10);
            mTimer.Elapsed += Timer_Elapsed;
        }

        /// <summary>
        ///到达事件间隔时触发
        /// </summary>
        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            lock (mRemoveList)
            {
                TimerModel tmpModel = null;
                foreach (int id in mRemoveList)
                {
                    mDictTimerModel.TryRemove(id, out tmpModel);
                }
                mRemoveList.Clear();
            }
            //遍历触发
            foreach (var model in mDictTimerModel.Values)
            {
                if (model.Time <= DateTime.Now.Ticks)
                {
                    model.Run();
                }
            }
        }
        /// <summary>
        /// 添加定时任务 某一时刻触发
        /// </summary>
        public void AddTimeEvent(DateTime dateTime, TimerDelegate timerDelegate)
        {
            //检查时间是否有效
            long delayTime = dateTime.Ticks - DateTime.Now.Ticks;
            if (delayTime <= 0) return;
            AddTimeEvent(delayTime, timerDelegate);
        }
        /// <summary>
        /// 添加定时任务 一段时间后触发
        /// </summary>
        /// <param name="delayTime">毫秒</param>
        public void AddTimeEvent(long delayTime, TimerDelegate timerDelegate)
        {
            TimerModel model = new TimerModel(id.Add_Get(), DateTime.Now.Ticks + delayTime, timerDelegate);
            mDictTimerModel.TryAdd(model.Id, model);
        }
    }
}
